home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
376-400
/
disk_376
/
plotter
/
src
/
berechnungsroutinen.c
< prev
next >
Wrap
Text File
|
1992-05-06
|
8KB
|
332 lines
/********************************************************************/
/**** ****/
/**** ****/
/**** Program : BerechnungsRoutinen.c ****/
/**** ****/
/**** Version : 03.71 ****/
/**** ****/
/**** Erstversion : 14.08.1988 ****/
/**** ****/
/**** Letzte Änderung : 05.08.1990 ****/
/**** ****/
/**** Compiliert mit : siehe MAKEFILE ****/
/**** ****/
/**** Gelinkt mit : siehe MAKEFILE ****/
/**** ****/
/********************************************************************/
/**** ****/
/**** ****/
/**** Copyright by Rüdiger Dreier ****/
/**** ****/
/**** ****/
/********************************************************************/
/* Einbinden der Include-Files */
#ifdef DEBUG
#include "Plotter.h"
#include <proto/tool.h>
#endif
#include <string.h>
#include <graphics/gfxmacros.h>
#include <proto/mathieeedoubbas.h>
#include <proto/mathieeedoubtrans.h>
#include <graphics/regions.h>
#include <proto/layers.h>
#include <stdio.h>
LONG MatheFehler;
char flagg;
SHORT Genauigkeiten[3]=
{
8,4,1
};
/* Funktion testet, ob ein Fehler aufgetreten ist */
VOID FehlerAbfrage(VOID)
{
/* Abfrage auf Mathe-Fehler */
if (MatheFehler)
{
request("OK","OK",BE_ERROR);
}
MatheFehler=0;
}
/* Zeichnet die n-te Ableitung der Funktion nr */
VOID __asm ZeichneFunktion(register __d0 USHORT nr,
register __d1 int Ableitung)
{
USHORT ZEICHNEN=TRUE;
double i,xalt,yalt,y;
ULONG OldIDCMP;
SHORT MaxXPos,Pos;
LONG H;
MaxXPos=(SHORT)(xx-Genauigkeiten[GE]);
SetAPen(RastPort,FARBE1);
/* Berechnet Position der x/y-Achse */
x0=Add(Mul(Div(Neg(xmn),Sub(xmp,xmn)),Flt(xx-1)),1.0);
y0= Add(Mul(Div(ymp,Sub(ymp,ymn)),Flt(yy-1)),1.0);
/* Bestimmt Zeichenmaßstab */
xm=Div(Flt(xx-1),Sub(xmp,xmn));
ym=Div(Flt(yy-1),Sub(ymp,ymn));
OldIDCMP=Window->IDCMPFlags;
ModifyIDCMP(Window,MOUSEBUTTONS);
if(!KoordinatenKreuz_gezeichnet)Loeschen();
SetAPen(RastPort,FARBE3);
flagg=1; /* ersten Punkt nur setzen */
StartBlock=Init_Mem(Formeln[nr]);
MatheFehler=Init_Block(StartBlock);
MatheFehler|=PreCalc(StartBlock,Konstantenstart);
if(MatheFehler)
{
FehlerAbfrage(); /* Es ist ein Fehler aufgetreten ! */
}
else
{
yalt=FunktionsWert(nr,xmn,Ableitung);
if(StartBlock->Fehler)flagg=2; /* NICHT MatheFehler */
xalt=xmn;
Verbinden(xalt,yalt);
for (Pos=1+Genauigkeiten[GE];Pos<=MaxXPos;Pos+=Genauigkeiten[GE])
{
i=Div(Sub(Flt(Pos),x0),xm);
/* Berechnet für einige x-Werte den Funktionswert und zeichnet ihn */
y=FunktionsWert(nr,i,Ableitung);
if(StartBlock->Fehler)
{
flagg=2;
}
Plotte(nr,xalt,i,yalt,y,0,Ableitung); /* Zeichnet den Punkt */
xalt=i;
yalt=y;
/* Abfrage auf Unterbrechnung */
H=EventAbfrage(Window,&msgInfo);
if (H==MOUSEBUTTONS)
{
if(request(BE_JA,BE_NEIN,BE_QUEST))
{
Pos=MaxXPos;
ZEICHNEN=FALSE;
}
}
}
if(ZEICHNEN)
{
y=FunktionsWert(nr,xmp,Ableitung);
Plotte(nr,xalt,xmp,yalt,y,0,Ableitung); /* Zeichnet den letzten Punkt */
}
/* Alles, was in FARBE3 über den Rand hinausgezeichnet wurde, wird hier gelöscht.*/
/* Dabei wird auch alles FARBE1 gelöscht. Beim Überschreiben wird darauf */
/* geachtet, daß FARBE3 nicht beeinträchtigt wird. Es wird nur ein Bit in der */
/* ersten BitPlane gesetzt, wenn dort FARBE3 erscheinen soll. Die zweite */
/* BitPlane wird nicht berührt. */
WaitBlit();
Forbid();
SetAPen(RastPort,FARBE0);
RectFill(RastPort,0,yy+Abstand+1,999,299);
RectFill(RastPort,0,0,1000,Abstand);
SetAPen(RastPort,FARBE1);
/* Und neu zeichnen */
SetWrMsk(RastPort,1);
if(Cmp(x0,0.0)>=0 && (Fix(x0)<(xx)))
{
Line(x0,1.0,x0,Flt(yy));
}
if(Cmp(y0,0.0)>=0 && Cmp(y0,Flt(yy))<1)
{
Line(1.0,y0,Flt(xx),y0);
}
zeichne();
SetWrMsk(RastPort,0xff);
Permit();
KoordinatenKreuz_gezeichnet=TRUE;
FehlerAbfrage(); /* Ist ein Fehler aufgetreten ? */
}
while(H=EventAbfrage(Window,&msgInfo));
ModifyIDCMP(Window,OldIDCMP);
Free_Block(StartBlock);
}
/* Arbeitet rekursiv, bis y-Abstand zweier Punkte klein genug */
VOID Plotte(nr,xl,xr,yl,yr,st,Ableitung)
unsigned short nr;
double xl,xr,yr,yl;
int st,Ableitung;
{
double x,y,a;
SHORT a1;
long Sprung;
/* GE liegt zwischen 1 und 3 */
Sprung=4-GE;
a=Sub(yl,yr);
if(Cmp(Abs(a),MAXLONG)==1)
{
a1=0;
}
else
{
a1=(abs(Fix(a))>Sprung);
}
/* Großer Sprung zwischen 2 Werten (z.B. Pole) */
if(a1)
{
/* Rekursionstiefe aufgrund der Zeichengenauigkeit */
if(st<=10 && Cmp(Min(yl,yr),Flt(yy))==-1 && Tst(Max(yr,yl))==1)
{
x=Div((Add(xl,xr)),2.0); /* x-Wert zwischen den beiden Stellen */
/* Berechnen des Funktionswertes */
y=FunktionsWert(nr,x,Ableitung);
Plotte(nr,xl,x,yl,y,st+1,Ableitung);
Plotte(nr,x,xr,y,yr,st+1,Ableitung);
}
else
{
flagg=1; /* 2 Punkte werden nicht verbunden */
/* z. B. 1/x bei x um 0 */
Verbinden(xr,yr);
}
}
else
{
Verbinden(xr,yr);
}
}
double FunktionsWert(nr,i,Ableitung)
int Ableitung;
unsigned short nr;
double i;
{
double ywert;
double y;
switch(Ableitung)
{
case 0:
{
MatheFehler|=Calc_P(&ywert,StartBlock,&i);
goto Einsprung_B1;
}
case 1:
{
double H1,H2,Help1;
if(Ableitung==1)
{
Help1=(Add(i,deltah));
MatheFehler|=Calc_P(&H1,StartBlock,&Help1);
MatheFehler|=Calc_P(&H2,StartBlock,&i);
ywert=Div(Sub(H1,H2),deltah);
Einsprung_B1:
y=Sub(y0,Mul(ym,ywert));
break;
}
case 2:
{
Help1=Add(i,deltahh);
H1=FunktionsWert(nr,i,1);
H2=FunktionsWert(nr,Help1,1);
ywert=Div(Sub(H1,H2),deltahh);
y=Sub(y0,ywert);
break;
}
}
}
return(y);
}
VOID Verbinden(xr,yr)
double xr,yr;
{
xr=Add(x0,Mul(xm,xr));
if(Cmp(Abs(yr),MAXLONG)==-1)
{
/* Wenn zu zeichen (innerhalb Zeichenbereichs) */
switch(flagg)
{
/* 2 Punkte nicht verbinden */
case 1:
{
Pset(xr,yr);
flagg=0;
break;
}
case 2:
{
flagg=1;
break;
}
case 0:
{
/* Zum nächsten Punkt zeichnen. Wenn Koordinaten wie bei Pset, dann */
/* wird nur ein Punkt gesetzt. */
DrawTo(xr,yr);
break;
}
}
}
else
{
flagg=1;
}
}
DOUBLE Max(a,b)
DOUBLE a,b;
{
if(a>b)
{
return(a);
}
else
{
return(b);
}
}
DOUBLE Min(a,b)
DOUBLE a,b;
{
if(a>b)
{
return(b);
}
else
{
return(a);
}
}
/* Hier kommen die Stub-Routinen, die für dieses Programm nicht */
/* gebraucht werden. Dadurch werden sie nicht angelinkt. */
VOID MemCleanup(VOID)
{
}
VOID chkabort(VOID)
{
}